/**
 * @description 由于现在Vue cli3关于PWA的文章实在不多 而且在国内pwa的网站也不多 所以暂时就放在根目录
 * @param self  表示 Service Worker 作用域, 也是全局变量
 * @param caches 表示缓存
 * @param skipWaiting 表示强制当前处在 waiting 状态的脚本进入 activate 状态
 * @param clients 表示 Service Worker 接管的页面
 */
//一、处理静态缓存
// 首先定义需要缓存的路径, 以及需要缓存的静态文件的列表, 这个列表也可以通过 Webpack 插件生成。
// !!!!readme:每次修改此文件均需要修改key的名字 目前暂定采用数字递增的形式
//updatecacheStorageKey
//设置缓存key
const time = new Date().getTime();
function getCacheKey () {
  let key = 'xlwpwa-';
  if (self.location.search.indexOf('production') != -1) {
    //生产
    const versionIndex = self.location.search.indexOf('version');
    //8:version=的字符数量
    const sliceIndex = versionIndex + 8;
    key = key + self.location.search.slice(sliceIndex);
  } else {
    //开发环境-并没有解决本地开发修改文件后刷新，但是热部署是可以的
    key = key + time;
  }
  return key;
}

const cacheList = [
  '/xlwvue/css/main.css',
  '/xlwvue/css/app.css',
  '/xlwvue/css/test.css',
  '/xlwvue/css/login.css',
  '/xlwvue/css/example.css',
  '/xlwvue/staticjs.js',
  '/xlwvue/manifest.json',
  '/xlwvue/pwaimg/favicon32.ico',
  '/xlwvue/pwaimg/favicon16.ico',
  '/xlwvue/pwaimg/applogo128.png',
  '/xlwvue/pwaimg/applogo144.png',
  '/xlwvue/pwaimg/applogo192.png',
  '/xlwvue/pwaimg/applogo256.png',
  '/xlwvue/pwaimg/applogo512.png',
  '/xlwvue/pwaimg/applogo.svg'
];
//借助 Service Worker, 可以在注册完成安装 Service Worker 时, 抓取资源写入缓存:
//调用 self.skipWaiting() 方法是为了在页面更新的过程当中, 新的 Service Worker 脚本能立即激活和生效。
self.addEventListener('install', e => {
  console.log('[Service Worker] Install');
  const cacheStorageKey = getCacheKey();
  e.waitUntil(
    caches.open(cacheStorageKey)
    .then(cache => {
      console.log('[Service Worker] Caching all: app shell and content');
      return cache.addAll(cacheList);
    })
    .then(() => self.skipWaiting())
  );
});
//二、处理动态缓存
//网页抓取资源的过程中, 在 Service Worker 可以捕获到 fetch 事件, 可以编写代码决定如何响应资源的请求:
//真实的项目当中, 可以根据资源的类型, 站点的特点, 可以专门设计复杂的策略。
//fetch 事件当中甚至可以手动生成 Response 返回给页面。
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(r => {
      console.log('[Service Worker] Fetching resource: ' + event.request.url);
      const cacheStorageKey = getCacheKey();
      return r || fetch(event.request).then(response => {
          console.log(response);
          return caches.open(cacheStorageKey).then(function(cache) {
          console.log('[Service Worker] Caching new resource: ' + event.request.url);
          cache.put(event.request, response.clone());
          return response;
        });
      });
    })
  );
});
//三、更新静态资源
//缓存的资源随着版本的更新会过期, 所以会根据缓存的字符串名称
//这里变量为 cacheStorageKey, 值用了 "xlwpwa-1"
//清除旧缓存, 可以遍历所有的缓存名称逐一判断决决定是否清除
//(备注: 简化的写法, Promise.all 中 return undefined 可能出错, 见评论):!!!!!!
//在新安装的 Service Worker 中通过调用 self.clients.claim() 取得页面的控制权,
//这样之后打开页面都会使用版本更新的缓存。旧的 Service Worker 脚本不再控制着页面之后会被停止。
self.addEventListener('activate', e => {
  e.waitUntil(
    caches.keys().then(cacheNames => {
        return Promise.all(
          cacheNames.filter(name => {
              return name !== getCacheKey();
          }).map(name => {
              return caches.delete(name);
          })
        ).then(() => self.clients.claim());
    })
  );
});


//消息通知的操作事件
self.addEventListener('notificationclick', event => {
  event.notification.close();
  //通知的参数
  const { notification } = event;
  //点击通知跳转页面
  if (Object.keys(notification.data).length !== 0) {
    if (notification.data.openUrl !== '') {
      event.waitUntil(self.clients.openWindow(notification.data.openUrl));
    }
  }
});

//消息通讯操作事件-具体目前本人不知道是用来做什么的暂时不进行扩充了
//serviceWorker 的能力决定它要处理的事情，网站页面的部分逻辑处理会转移到 serviceWorker 层进行处理，这里就要页面层和 serviceWorker 层进行交互来实现消息通讯。
self.addEventListener('message', event => {});

self.addEventListener('push', event => {
  // 此处可以做任何事
  const data = event.data.json();

  if (!(self.Notification && self.Notification.permission === 'granted')) {
    return;
  }
  self.registration.showNotification(data.title, {
    body: data.body
  });
});
